package cn.coder.toolkit;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Decimal extends BigDecimal {

    private static final long serialVersionUID = 1L;

    public static final Decimal ZERO = Decimal.of("0");

    // 构造方法(私有)

    private Decimal(String value) {
        super(value);
    }

    private Decimal(Number value) {
        super(value.toString());
    }

    // 构造方法(公开)

    public static Decimal of(String value) {
        return new Decimal(value);
    }

    public static Decimal of(Number value) {
        return new Decimal(value);
    }

    // 内部转换

    private static Decimal convertBigDecimalToDecimal(BigDecimal value) {
        return Decimal.of(value.toString());
    }

    private static BigDecimal convertNumberToBigDecimal(Number value) {
        return value instanceof BigDecimal ? (BigDecimal) value : new BigDecimal(value.toString());
    }


    // 大小比较

    public boolean lt(Number value) {
        return this.compareTo(convertNumberToBigDecimal(value)) < 0;
    }

    public boolean gt(Number value) {
        return this.compareTo(convertNumberToBigDecimal(value)) > 0;
    }

    public boolean lte(Number value) {
        return this.compareTo(convertNumberToBigDecimal(value)) <= 0;
    }

    public boolean gte(Number value) {
        return this.compareTo(convertNumberToBigDecimal(value)) >= 0;
    }

    public boolean eq(Number value) {
        return this.compareTo(convertNumberToBigDecimal(value)) == 0;
    }

    // 加减乘除, add/subtract/multiply/divide/divideZeroSafely

    public Decimal a(Number value) {
        return convertBigDecimalToDecimal(this.add(convertNumberToBigDecimal(value)));
    }

    public Decimal s(Number value) {
        return convertBigDecimalToDecimal(this.subtract(convertNumberToBigDecimal(value)));
    }

    public Decimal m(Number value) {
        return convertBigDecimalToDecimal(this.multiply(convertNumberToBigDecimal(value)));
    }

    public Decimal d(Number value, int scale, RoundingMode mode) {
        return convertBigDecimalToDecimal(0 == value.doubleValue() ? BigDecimal.ZERO : this.divide(convertNumberToBigDecimal(value), scale, mode));
    }

    public Decimal dd(Number value, int scale) {
        return d(value, scale, RoundingMode.DOWN);
    }

    public Decimal ddt(Number value) {
        return d(value, 2, RoundingMode.DOWN);
    }

    // 精度调整, precision

    public Decimal p(int scale, RoundingMode mode) {
        return convertBigDecimalToDecimal(this.setScale(scale, mode));
    }

    public Decimal pd(int scale) {
        return convertBigDecimalToDecimal(this.setScale(scale, RoundingMode.DOWN));
    }

    public Decimal pdt() {
        return convertBigDecimalToDecimal(this.setScale(2, RoundingMode.DOWN));
    }

    // 测试

    public static void main(String[] args) {
        System.out.println(Decimal.of("1.54321").m(2).pdt());
    }

}
